package com.xiaouyudeguang.common.handler;

import com.xiaouyudeguang.common.annotations.ApiSocket;
import com.xiaouyudeguang.common.event.WsEvent;
import com.xiaouyudeguang.common.manager.WebSocketSessionManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

/**
 * ws消息处理类
 */
@Slf4j
@ApiSocket("websocket")
public class WebSocketHandler extends AbstractWebSocketHandler {

    @Autowired(required = false)
    private ApplicationContext context;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.debug("建立ws连接");
        WebSocketSessionManager.add(session.getId(), session);
        context.publishEvent(WsEvent.builder().type(WsEvent.Type.CONNECTED).sessionId(session.getId()).build());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.debug("发送文本消息");
        // 获得客户端传来的消息
        String payload = message.getPayload();
        log.debug("server 接收到消息 " + payload);
        session.sendMessage(new TextMessage("ok"));
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
        log.debug("发送二进制消息");
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.debug("异常处理");
        WebSocketSessionManager.removeAndClose(session.getId());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        log.debug("关闭ws连接");
        WebSocketSessionManager.removeAndClose(session.getId());
        context.publishEvent(WsEvent.builder().type(WsEvent.Type.DISCONNECT).sessionId(session.getId()).build());
    }
}
